#include "cilent.h"
#include <openssl/md5.h>
int main(int argc, char *argv[]) {
    ARGS_CHECK(argc, 3);

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(sockfd, -1, "socket");

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_addr.s_addr = inet_addr(argv[1]);

    int ret = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    ERROR_CHECK(ret, -1, "connect");

    char buf[4096] = {0};
    int authenticated = 0; // 认证状态标志
    char md5_str[1024]={0};
    Train train;
    fd_set readset;

    while(1) {
        FD_ZERO(&readset);
        FD_SET(STDIN_FILENO, &readset);
        FD_SET(sockfd, &readset);

        select(sockfd + 1, &readset, NULL, NULL, NULL);

if(FD_ISSET(STDIN_FILENO, &readset)) {
            memset(buf, 0, sizeof(buf));
            memset(&train, 0, sizeof(train));
            memset(md5_str,0,sizeof(md5_str));
            // 获取用户输入
            if (fgets(buf, sizeof(buf), stdin) == NULL) {
                // 处理EOF（Ctrl+D）
                train.commend = QUIT;
                send(sockfd, &train, sizeof(train.commend) + sizeof(train.length) + train.length, 0);
                break;
            }
            // 移除换行符
            buf[strcspn(buf, "\n")] = '\0';

            if(strlen(buf) == 0) {
                // 空行视为退出
                train.commend = QUIT;
                send(sockfd, &train, sizeof(train.commend) + sizeof(train.length) + train.length, 0);
                break;
            }

            // 解析命令
            if (parse_command(buf, &train) == 0) {
                // 处理认证命令
                if (train.commend == LOGIN || train.commend == REGISTER) {
                    // 从命令数据中提取用户名和密码
                    char *username = strtok(train.data, " ");
                    char *password = strtok(NULL, " ");
                    
                    if (username && password) {
                        // 执行认证操作
                        if (auth_action(sockfd, train.commend, username, password) == 0) {
                            authenticated = (train.commend == LOGIN);
                        }
                    } else {
                        printf("错误：需要提供用户名和密码\n");
                    }
                    continue;
                }
                
                // 检查是否已认证
                if (!authenticated && train.commend != QUIT) {
                    printf("错误：请先登录 (使用 login 命令)\n");
                    continue;
                }
                
                // 发送命令到服务器
                send(sockfd, &train, sizeof(train.commend) + sizeof(train.length) + train.length, 0);
                
                // 处理特殊命令
                if(train.commend == PUTS){
                    // Compute_file_md5(train.data,md5_str);
                    MD5_CTX ctx;
                    MD5_Init(&ctx);
                    char buf[4096];
                    int fd=open(train.data,O_RDWR);
                    while(1){
                        bzero(buf,sizeof(buf));
                        ssize_t sret=read(fd,buf,sizeof(buf));
                        MD5_Update(&ctx,buf,sret);
                        if(sret == 0){
                            break;
                        }
                    }
                    unsigned char md[16];
                    MD5_Final(md,&ctx);
                    char str[33] = {0};
                    for(int i = 0; i < 16; ++i){
                        char temp[3] = {0};
                        sprintf(temp,"%02x",md[i]);
                        strcat(str,temp);
                    }
                    printf("str = %s\n",str);
                    putsCommand(sockfd,str,train.data);
                }
                else if(train.commend == GETS){
                    getsCommand(sockfd);
                }
                else if (train.commend == QUIT) {
                    break;
                }
            }
}

if(FD_ISSET(sockfd, &readset)) {
    memset(&train, 0, sizeof(train));
    int sret = recv(sockfd, &train.commend, sizeof(train.commend), 0);
    if(sret == 0) {
        printf("服务器已断开连接\n");
        break;
    } else if (sret < 0) {
        perror("recv commend error");
        break;
    }

    // 接收长度
    sret = recv(sockfd, &train.length, sizeof(train.length), 0);
    if (sret <= 0) {
        perror("recv length error");
        break;
    }

    // 接收数据
    if (train.length > 0) {
        sret = recv(sockfd, train.data, train.length, 0);
        if (sret <= 0) {
            perror("recv data error");
            break;
        }
    }
    train.data[train.length] = '\0'; // 确保字符串结束

    // 处理服务器响应
    switch(train.commend) {
    case ERROR_COMMAND:
        printf("错误命令: %s\n", train.data);
        break;

    case LOGIN_SUCCESS:
    case REGISTER_SUCCESS:
        // 这些应该已经在auth_action中处理
        break;

    default:
        // 显示普通命令结果
        printf("%s\n", train.data);
    }
}
}

close(sockfd);
return 0;
}
